/*
 *  Cero Project - Copyright   2006 The Cero Developement Team 
 *  (Michael Laguerre, Camille Roux, Matthieu Segret, Mathieu Sivade) 
 * 
 *  This program is free software; you can redistribute it and/or modify it 
 *  under the terms of the GNU General Public License as published by the Free 
 *  Software Foundation; either version 2 of the License, or (at your option) 
 *  any later version.
 * 
 *  This program is distributed in the hope that it will be useful, but 
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 *  for more details.
 */

package org.ceroproject.games.base;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import org.ceroproject.games.Zone;
import org.ceroproject.games.ZonesGroup;


/**
 * Groups several zones and identify them by their name
 * 
 * @author Telem
 */
public class ZonesBase implements ZonesGroup {

	/** The zones of this group */
	private HashMap<String, Zone> zones = new HashMap<String, Zone>();

	public void clear() {
		zones.clear();
	}

	/**
	 * Returns whether the zone named 'name' is in this group
	 * 
	 * @param name
	 *            the name of the zone
	 * @return true if the zone has been removed, false otherwise
	 */
	public boolean contains(Object name) {
		return zones.containsValue(name);
	}

	/**
	 * Returns the zone named 'name'
	 * 
	 * @param name
	 *            the name of the zone
	 * @return the zone named 'name'
	 */
	public Zone get(String name) {
		return zones.get(name);
	}

	public boolean isEmpty() {
		return zones.isEmpty();
	}

	/**
	 * Adds the zone zone to the group
	 * 
	 * @param zone
	 *            the zone to add
	 * @return whether the zone was added or not
	 */
	public boolean add(Zone zone) {
		if (zones.get(zone.getName()) != null)
			throw new RuntimeException(
					"You can't add a zone if it already exists");
		return (zones.put(zone.getName(), zone) != null);
	}

	/**
	 * Removes the zone named 'name'
	 * 
	 * @param name
	 *            the name of teh zone to remove
	 * @return true if the zone was removed, false otherwise
	 */
	public boolean remove(Object name) {
		return (zones.remove(name) != null);
	}

	public int size() {
		return zones.size();
	}

	public Collection<Zone> getZones() {
		return zones.values();
	}

	public Iterator<Zone> iterator() {
		return zones.values().iterator();
	}

	public Object[] toArray() {
		return zones.values().toArray();
	}

	public <T> T[] toArray(T[] ar) {
		return zones.values().toArray(ar);
	}

	/**
	 * Returns whether all the zones in col are contained in this group
	 * 
	 * @param col
	 *            the collection of zones to check
	 * @return true if all the zones are contained, false otherwise
	 */
	public boolean containsAll(Collection<?> col) {
		return zones.values().containsAll(col);
	}

	/**
	 * Adds all the zones in col
	 * 
	 * @param col
	 *            the collection of zones to add
	 * @return true if all the zones were added, false otherwise
	 */
	public boolean addAll(Collection<? extends Zone> col) {
		for (Zone z : col)
			zones.put(z.getName(), z);
		return false;
	}

	/**
	 * Removes all the zones in col from this group
	 * 
	 * @param col
	 *            the collection of zones to remove
	 * @return true if all the zones were removed, false otherwise
	 */
	public boolean removeAll(Collection<?> col) {
		boolean noprob = true;
		for (Object z : col)
			noprob &= (zones.remove(((Zone) z).getName()) != null);
		return noprob;
	}

	/**
	 * Unsupported operation.
	 * @throws UnsupportedOperationException always.
	 */
	public boolean retainAll(Collection<?> col) {
		throw new UnsupportedOperationException();
	}

}
